package com.lzk.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.lzk.auth.mapper.*;
import com.lzk.auth.service.DeviceService;
import com.lzk.auth.service.SysUserService;
import com.lzk.auth.service.TypeService;
import com.lzk.model.system.*;
import com.lzk.auth.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzk.vo.system.OrderVO;
import com.lzk.vo.system.PlanVo;
import com.lzk.vo.system.StartPlanVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
import java.util.concurrent.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lzk
 * @since 2023-12-30
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, SysOrder> implements OrderService {
    @Autowired
    ProductMapper productMapper;

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    OrderStatusMapper orderStatusMapper;
    @Autowired
    TypeService typeService;

    @Autowired
    DeviceMapper deviceMapper;

    @Autowired
    SysUserService sysUserService;

    @Autowired
    PlanMapper planMapper;

    @Autowired
    DeviceService deviceService;

    @Autowired
    private OrderService orderService;
    @Override
    public List<SysOrder> getAll(OrderVO orderVo, long page, long limit) {
        Integer orderStatus = orderVo.getOrderStatus();
        Long uid = orderVo.getUid();
        long offset = (page - 1) * limit;
        LambdaQueryWrapper<SysOrder> wrapper = new LambdaQueryWrapper<>();
        if (null != orderStatus) {
            wrapper.eq(SysOrder::getOrderStatus, orderStatus);

        }
        if (null != uid) {
            wrapper.eq(SysOrder::getUId, uid);
        }
        wrapper.last("LIMIT " + offset + "," + limit);
        List<SysOrder> sysOrders = baseMapper.selectList(wrapper);
        System.out.println("-----------------");
        System.out.println(sysOrders.size());

        for (SysOrder sysOrder : sysOrders) {
            Integer status1 = sysOrder.getOrderStatus();
            SysOrderStatus status = orderStatusMapper.selectById(status1);
            sysOrder.setOStatus(status.getStatusName());
            long uId = sysOrder.getUId();
            SysUser sysUser = sysUserMapper.selectById(uId);
            sysOrder.setUName(sysUser.getName());
            String sysOrderPId = sysOrder.getPId();
            String[] pIds = sysOrderPId.split(",");
            List<String> pNames = new ArrayList<>();
            for (String pId : pIds) {
                Integer pid = Integer.parseInt(String.valueOf(pId));
                SysProduct sysProduct = productMapper.selectById(pid);
//                Integer pType = sysProduct.getPType();
//                SysType type = typeService.getById(pType);
//                String pName = type.getName();
//                System.out.println("----------");
                String pName = sysProduct.getPName();
                System.out.println(pName);
                pNames.add(pName);
            }
            sysOrder.setPName(pNames);

        }
//        for (SysOrder sysOrder : sysOrders) {
//            System.out.println("------------------------");
//            System.out.println(sysOrder.getPName());
//        }
        return sysOrders;
    }

    @Override
    public void startPlan(StartPlanVO startPlanVO) {
        //获得当前的用户id
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentPrincipalName = authentication.getName();
        SysUser user = sysUserService.getUserByUsername(currentPrincipalName);
        Long id = startPlanVO.getId();
        //根据id更改id状态
        UpdateWrapper<SysOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id); // 根据ID作为更新条件
        updateWrapper.set("order_status", 2);
        orderService.update(updateWrapper);
        //根据id获得订单
        SysOrder sysOrder = baseMapper.selectById(id);
        LocalDateTime dateTime = LocalDateTime.now();
        //新建计划对象
        SysPlan sysPlan = new SysPlan();
        sysPlan.setOrderId(id);
        sysPlan.setStartTime(dateTime);
        //获取用户选择的设备id
        List<Long> ids1 = startPlanVO.getIds();
        //通过订单获得产品的数量
        String pminCount = sysOrder.getPCount();
        //获得产品id
        String pId = sysOrder.getPId();
        String[] pIds = pId.split(",");
        String[] minCounts = pminCount.split(",");
        int total = 0;
        //计算产品总数
        for (String minCount : minCounts) {
            int minCountNumber = Integer.parseInt(String.valueOf(minCount));
            total += minCountNumber;
        }
        System.out.println("-------------------");
        System.out.println("total"+total);
        //获取产品种类
        int pIdNumber = Integer.parseInt(String.valueOf(pIds[0]));
        SysProduct sysProduct = productMapper.selectById(pIdNumber);
        Integer pType = sysProduct.getPType();
        //获取当前产品的能量值
        SysType type = typeService.getById(pType);
        int energy = type.getEnergy();
        System.out.println("---------------");
        System.out.println("energy: "+energy);
        int time = (int) Math.ceil((double) (energy) * total / (ids1.size()) / 100);
        System.out.println("-------------");
        System.out.println(time);
        LocalDateTime endTime = dateTime.plusHours(time);
        sysPlan.setEndTime(endTime);
        //改变选中设备的状态
        for (Long dId : ids1) {
            //设置计时器
            scheduleResetToIdle(dId, endTime,id);
            UpdateWrapper<SysDevice> updateWrapper1 = new UpdateWrapper<>();
            updateWrapper1.eq("id", dId); // 根据ID作为更新条件
            updateWrapper1.set("device_status", 2);
            deviceService.update(updateWrapper1);
        }
        String dIds = ids1.stream()
                .map(Object::toString) // 将Long类型映射为String类型
                .collect(Collectors.joining(","));
        sysPlan.setDeviceId(dIds);
        sysPlan.setUserId(user.getId());
        planMapper.insert(sysPlan);

    }


    @Override
    public PlanVo deviceFree(Long id) {
        SysOrder sysOrder = baseMapper.selectById(id);
        String pminCount = sysOrder.getPCount();
        String[] minCounts = pminCount.split(",");
        int total = 0;
        for (String minCount : minCounts) {
            int minCountNumber = Integer.parseInt(String.valueOf(minCount));
            total += minCountNumber;
        }

        System.out.println(total);
        List<Long> ids = new ArrayList<>();
        String pId = sysOrder.getPId();
        String[] pIds = pId.split(",");
        int pIdNumber = Integer.parseInt(String.valueOf(pIds[0]));
        SysProduct sysProduct = productMapper.selectById(pIdNumber);
        Integer pType = sysProduct.getPType();
        SysType type = typeService.getById(pType);
        LambdaQueryWrapper<SysDevice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDevice::getDType, pType);
        wrapper.eq(SysDevice::getDStatus, 1);
        List<SysDevice> sysDevices = deviceMapper.selectList(wrapper);
        for (SysDevice sysDevice : sysDevices) {
            Long id1 = sysDevice.getId();
            System.out.println(id1);
            ids.add(id1);
        }
        int totalEnergy = (type.getEnergy()) * total;
        int minCount = (int) Math.ceil((double) (totalEnergy) / 100);

        PlanVo planVo = new PlanVo(ids, minCount);
        return planVo;
    }

    //统计订单状态
    @Override
    public List<Integer> OrderStatus() {

        List<SysOrder> sysOrders = baseMapper.selectList(null);
        List<Integer> statusCounts = new ArrayList<>(Collections.nCopies(5, 0));


        for (SysOrder sysOrder : sysOrders) {
            int orderStatus = sysOrder.getOrderStatus();

            // 获取当前状态的计数，将其加一，并更新列表中对应状态的计数
            int count = statusCounts.get(orderStatus);
            statusCounts.set(orderStatus, count + 1);
        }

        return statusCounts;
    }

    @Override
    public List<SysOrder> getPersonalOrder(OrderVO orderVo,long page,long limit) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String currentPrincipalName = authentication.getName();
        SysUser user = sysUserService.getUserByUsername(currentPrincipalName);

        Integer orderStatus = orderVo.getOrderStatus();
        Long uid = orderVo.getUid();
        long offset = (page - 1) * limit;
        LambdaQueryWrapper<SysOrder> wrapper = new LambdaQueryWrapper<>();
        if (null != orderStatus) {
            wrapper.eq(SysOrder::getOrderStatus, orderStatus);

        }
        if (null != uid) {
            wrapper.eq(SysOrder::getUId, uid);
        }
        wrapper.eq(SysOrder::getUId,user.getId());
        wrapper.last("LIMIT " + offset + "," + limit);
        List<SysOrder> sysOrders = baseMapper.selectList(wrapper);
        System.out.println("-----------------");
        System.out.println(sysOrders.size());

        for (SysOrder sysOrder : sysOrders) {
            Integer status1 = sysOrder.getOrderStatus();
            SysOrderStatus status = orderStatusMapper.selectById(status1);
            sysOrder.setOStatus(status.getStatusName());
            long uId = sysOrder.getUId();
            SysUser sysUser = sysUserMapper.selectById(uId);
            sysOrder.setUName(sysUser.getName());
            String sysOrderPId = sysOrder.getPId();
            String[] pIds = sysOrderPId.split(",");
            List<String> pNames = new ArrayList<>();
            for (String pId : pIds) {
                Integer pid = Integer.parseInt(String.valueOf(pId));
                SysProduct sysProduct = productMapper.selectById(pid);
//                Integer pType = sysProduct.getPType();
//                SysType type = typeService.getById(pType);
//                String pName = type.getName();
//                System.out.println("----------");
                String pName = sysProduct.getPName();
                System.out.println(pName);
                pNames.add(pName);
            }
            sysOrder.setPName(pNames);

        }
//        for (SysOrder sysOrder : sysOrders) {
//            System.out.println("------------------------");
//            System.out.println(sysOrder.getPName());
//        }
        return sysOrders;
    }


    private void scheduleResetToIdle(Long deviceId, LocalDateTime endTime,Long orderId) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                // 设置设备状态为空闲状态（例如，1代表空闲状态）
                UpdateWrapper<SysDevice> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", deviceId);
                updateWrapper.set("device_status", 1);
                deviceService.update(updateWrapper);
                //订单状态置为已完成
                UpdateWrapper<SysOrder> updateWrapper1 = new UpdateWrapper<>();
                updateWrapper1.eq("id", orderId);
                updateWrapper1.set("order_status", 3);
                orderService.update(updateWrapper1);

                // 取消计时器
                timer.cancel();
            }
        }, Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
    }


}
